package com.cms.component.menu;

import com.cms.common.model.entity.AdminUser;
import com.cms.common.model.entity.Permission;
import com.cms.common.model.entity.Roles;
import com.cms.common.model.vo.Menu;
import com.cms.plugin.hook.HookServices;
import com.cms.common.hook.vo.HookParams;
import com.cms.common.hook.vo.HookResult;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;

/**
 * Copyright (c) Since 2024 ThinkCms - All Rights Reserved
 *
 * @author what
 * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 * @Date 2024/12/11 10:12
 */

public class MenuConfig {
    public static List<Menu> getMenus(AdminUser adminUser, HttpServletRequest request) {
        List<Menu> allMenus = new ArrayList<>();

        // 通过角色控制要显示的菜单
        if (adminUser == null) {
            return allMenus;
        }

        //图标库 https://fontawesome.com.cn/v4/icons

        allMenus.add(Menu.createMenu("首页", "el-icon-s-home", "/admin/dashboard", "dashboard"));

        List<Menu> contentChildrenList = new ArrayList<>();
        contentChildrenList.add(Menu.createMenu("文章列表", "el-icon-collection", "/admin/article", ""));
        contentChildrenList.add(Menu.createMenu("文章分类", "", "/admin/article_category", ""));

        List<String> articlePrefixes = new ArrayList<>();
        articlePrefixes.add("article");
        articlePrefixes.add("article_category");

        allMenus.add(Menu.createMenu("内容管理", "el-icon-notebook-2", "/admin/article", contentChildrenList, articlePrefixes));


        List<Menu> adminUserChildrenList = new ArrayList<>();
        adminUserChildrenList.add(Menu.createMenu("后台用户", "", "/admin/users", ""));
        adminUserChildrenList.add(Menu.createMenu("角色管理", "", "/admin/roles", ""));
        List<String> prefixes = new ArrayList<>();
        prefixes.add("users");
        prefixes.add("roles");
        allMenus.add(Menu.createMenu("用户管理", "el-icon-user", "/admin/users", adminUserChildrenList, prefixes));


        List<Menu> pluginChildrenList = new ArrayList<>();
        pluginChildrenList.add(Menu.createMenu("插件设置", "", "/admin/plugins", ""));
        pluginChildrenList.add(Menu.createMenu("插件市场", "", "/admin/plugin_markets", ""));
        List<String> pluginPrefixes = new ArrayList<>();
        pluginPrefixes.add("plugins");
        pluginPrefixes.add("plugin_markets");
        allMenus.add(Menu.createMenu("插件扩展", "el-icon-circle-plus-outline", "/admin/plugins",pluginChildrenList, pluginPrefixes));


        List<Menu> settingChildrenList = new ArrayList<>();
        settingChildrenList.add(Menu.createMenu("个人信息", "", "/admin/account", ""));
        settingChildrenList.add(Menu.createMenu("语言设置", "", "/admin/language", ""));
        List<String> settingPrefixes = new ArrayList<>();
        settingPrefixes.add("account");
        settingPrefixes.add("language");
        allMenus.add(Menu.createMenu("系统设置", "el-icon-setting", "/admin/account", settingChildrenList, settingPrefixes));


        HookParams hookParams = new HookParams();
        hookParams.getRequestParams().put("menuList", allMenus);
        HookResult hookResult = HookServices.regHook("admin.menus", hookParams);
        if (hookResult.getCode() == 0) {
            allMenus = (List<Menu>) hookParams.getRequestParams().get("menuList");
        }


        List<Menu> finalMenuList = null;
        String activeMenuRoute = request.getRequestURI();
        activeMenuRoute = activeMenuRoute.substring(activeMenuRoute.indexOf("/admin/"));
        activeMenuRoute = activeMenuRoute.replace("/admin/", "").split("/")[0];
        if (adminUser.getId() > 1) {
            Roles roles = adminUser.getRoles();
            if (roles != null) {
                List<Permission> permissions = roles.getPermissions();
                List<String> routeList = new ArrayList<>();
                for (Permission permission : permissions) {
                    routeList.add(permission.getRoute());
                }
                finalMenuList = getFinalMenuList(null, allMenus, routeList, activeMenuRoute);
            }
            return finalMenuList;
        } else {
            finalMenuList = getFinalMenuList(null, allMenus, activeMenuRoute);
            return finalMenuList;
        }
    }

    private static List<Menu> getFinalMenuList(Menu parentMenu, List<Menu> allMenus, List<String> routes, String activeMenuRoute) {
        List<Menu> finalMenus = new ArrayList<>();
        for (Menu menu : allMenus) {
            if (menu.getChildren() != null) {
                List<Menu> finalChildMenus = getFinalMenuList(menu, menu.getChildren(), routes, activeMenuRoute);
                if (finalChildMenus.size() > 0) {
                    menu.setChildren(finalChildMenus);
                    finalMenus.add(menu);
                }
            } else if (routes.contains(menu.getRoute())) {
                String activeRoute = menu.getRoute().replace("/admin/", "").split("/")[0];
                if (activeRoute.equals(activeMenuRoute) || (menu.getPrefixes() != null && menu.getPrefixes().contains(activeMenuRoute))) {
                    menu.setActive(true);
                    if (parentMenu != null) {
                        parentMenu.setOpen(true);
                    }
                }
                finalMenus.add(menu);
            }
        }
        return finalMenus;
    }

    private static List<Menu> getFinalMenuList(Menu parentMenu, List<Menu> allMenus, String activeMenuRoute) {
        List<Menu> finalMenus = new ArrayList<>();
        for (Menu menu : allMenus) {
            if (menu.getChildren() != null) {
                List<Menu> finalChildMenus = getFinalMenuList(menu, menu.getChildren(), activeMenuRoute);
                if (finalChildMenus.size() > 0) {
                    menu.setChildren(finalChildMenus);
                    finalMenus.add(menu);
                }
            } else {
                String[] activeRoutes = menu.getRoute().split("/admin/");
                String activeRoute = activeRoutes[1].split("/")[0];
                if (activeRoute.equals(activeMenuRoute) || (menu.getPrefixes() != null && menu.getPrefixes().contains(activeMenuRoute))) {
                    menu.setActive(true);
                    if (parentMenu != null) {
                        parentMenu.setOpen(true);
                    }
                }
                finalMenus.add(menu);
            }
        }
        return finalMenus;
    }
}
